package com.hxgis.common.service.impl;

import com.es.common.EsAggCondition;
import com.es.common.domain.EsCondition;
import com.es.wrapper.DataWrapper;
import com.hxgis.common.base.StationCache;
import com.hxgis.common.conare.RainFeatureArea;
import com.hxgis.common.conare.RainFeatureTime;
import com.hxgis.common.entity.RainDayInfo;
import com.hxgis.common.entity.RainstormFeatureInfo;
import com.hxgis.common.entity.Station;
import com.hxgis.common.repository.RainDayInfoRepository;
import com.hxgis.common.repository.RainstormFeatureInfoRepository;
import com.hxgis.common.service.RainstormFeatureService;
import com.hxgis.common.service.StationService;
import com.hxgis.common.utils.RectField;
import com.hxgis.common.utils.TimeUtil;
import com.hxgis.common.vo.AreaFrequencyVO;
import com.hxgis.common.vo.SingleFrequencyVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author cqj
 * @version 1.0
 * @date 2019/10/10 8:56
 */
@Service
@Slf4j
public class RainstormFeatureServiceImpl implements RainstormFeatureService {

    @Autowired
    private StationService stationService;

    @Autowired
    private RainDayInfoRepository rainDayInfoRepository;

    @Autowired
    private RainstormFeatureInfoRepository featureInfoRepository;



    @Override
    public void transSingleStromByDay(String startTime, String endTime) {
        List<RainstormFeatureInfo> rainstormFeatureInfos = new ArrayList<>();
        List<Station> stations = stationService.selectAll();
        long st = System.currentTimeMillis();
//        List<RainDayInfo> rainDayInfos = new ArrayList<>();

        //todo xxxxxx
        List<String> stationNos = stations.stream().map(Station::getStationNo).map(String::valueOf).collect(Collectors.toList());

        EsCondition rainDayCondition = EsCondition.getEsCondition();
        rainDayCondition.gte("time",Long.parseLong(startTime)).lte(Long.parseLong(endTime));
        rainDayCondition.lte("rainFall",20000);
        rainDayCondition.size(1000000);
        List<RainDayInfo> rainDayInfos = rainDayInfoRepository.selectList(rainDayCondition);


        Map<String, List<RainDayInfo>> collect1 = rainDayInfos.stream().collect(Collectors.groupingBy(RainDayInfo::getStationNo));
        collect1.forEach((key,value) -> {
            if (!CollectionUtils.isEmpty(value)){
                //todo 可以不用按照时间排序，排序了最好，因为查询都是查的原始数据
                Collections.sort(value,((o1, o2) -> {
                    return (int)(o1.getTime()-o2.getTime());
                }));
                Map<Long, RainstormFeatureInfo> featureInfoMap = transFeatureStrom(value, key);
                if(!CollectionUtils.isEmpty(featureInfoMap)){
                    featureInfoMap.forEach((key1,value1) -> {
                        rainstormFeatureInfos.add(value1);
                    });
                }
            }
            log.info("当前正在计算的站点是:{}，用时:{}",key,System.currentTimeMillis() -st);
        });

        //todo yyyyyyy
        log.info("{}到{}的全国持续性暴雨特征数据用时:{}",startTime,endTime,System.currentTimeMillis() -st);
        featureInfoRepository.saveBatch(rainstormFeatureInfos);
        System.out.println(rainstormFeatureInfos.size());
    }

    @Override
    public void delSingleStromByDay(String startTime, String endTime) {
        EsCondition esCondition = EsCondition.getEsCondition();
        esCondition.gte("time",startTime).lte(endTime);
        esCondition.size(1000000);
        featureInfoRepository.deleteBySearch(esCondition);
    }


    @Override
    public void transSingleStrom(String startYear, String endYear) {
        List<RainstormFeatureInfo> rainstormFeatureInfos = new ArrayList<>();
        List<Station> stations = stationService.selectAll();
        long st = System.currentTimeMillis();
        List<RainDayInfo> rainDayInfos = new ArrayList<>();

        //todo xxxxxx
        List<String> stationNos = stations.stream().map(Station::getStationNo).map(String::valueOf).collect(Collectors.toList());

        for (int j = 1; j <= 12 ; j++){
            EsCondition rainDayCondition = EsCondition.getEsCondition();
            rainDayCondition.gte("time",Long.parseLong(TimeUtil.getFirstDayOfMonth(Integer.valueOf(startYear),j))).lte(Long.parseLong(TimeUtil.getLastDayOfMonth(Integer.valueOf(endYear),j)));
            rainDayCondition.lte("rainFall",20000);
            rainDayCondition.size(1000000);
            List<RainDayInfo> rainDayInfosSub = rainDayInfoRepository.selectList(rainDayCondition);
            if (!CollectionUtils.isEmpty(rainDayInfosSub)){
                rainDayInfos.addAll(rainDayInfosSub);
            }
        }



//        EsCondition rainDayCondition = EsCondition.getEsCondition();
//        rainDayCondition.gte("time",Long.parseLong(startTime)).lt(Long.parseLong(endTime));
//        rainDayCondition.lte("rainFall",10000);
//        rainDayCondition.in("stationNo",com.hxgis.common.utils.CollectionUtils.convertCollectionString(stationNos));
//        rainDayCondition.size(1000000);
//        List<RainDayInfo> rainDayInfos = rainDayInfoRepository.selectList(rainDayCondition);


        Map<String, List<RainDayInfo>> collect1 = rainDayInfos.stream().collect(Collectors.groupingBy(RainDayInfo::getStationNo));
        collect1.forEach((key,value) -> {
            if (!CollectionUtils.isEmpty(value)){
                //todo 可以不用按照时间排序，排序了最好，因为查询都是查的原始数据
                Collections.sort(value,((o1, o2) -> {
                    return (int)(o1.getTime()-o2.getTime());
                }));
                Map<Long, RainstormFeatureInfo> featureInfoMap = transFeatureStrom(value, key);
                if(!CollectionUtils.isEmpty(featureInfoMap)){
                    featureInfoMap.forEach((key1,value1) -> {
                        rainstormFeatureInfos.add(value1);
                    });
                }
            }
            log.info("当前正在计算的站点是:{}，用时:{}",key,System.currentTimeMillis() -st);
        });

        //todo yyyyyyy
        log.info("{}到{}的全国持续性暴雨特征数据用时:{}",startYear,endYear,System.currentTimeMillis() -st);
        featureInfoRepository.saveBatch(rainstormFeatureInfos);
        System.out.println(rainstormFeatureInfos.size());
    }

    @Override
    public void featureAreaStrom(String startTime, String endTime, List<String> stationNos) {
        // 拿出这段时间的站点的暴雨过程
        List<RainstormFeatureInfo> rainstormFeatureInfos = selectList(startTime, endTime, com.hxgis.common.utils.CollectionUtils.convertCollectionString(stationNos));
        //根据暴雨过程标识 进行处理每个暴雨过程 进行分组
        Map<String, List<RainstormFeatureInfo>> courseNumList = RectField.conversionIndexToList(rainstormFeatureInfos, "courseNum");
        // 将有时间交集的处理成一个过程  再进行站点区域筛选成一个区域
        List<RainFeatureTime> rainstormTimes = converRainstormTime(courseNumList);

        // 计算每个站点的区域点
        List<RainFeatureArea> rainstormAreas = rainstormAreas(rainstormTimes);

        //todo xxx  这里应该是for循环 测试只取了一个进行的循环
        //第一步找核心区域 如果整个大小小于3个就不用计算了直接丢掉

        for (RainFeatureArea rainFeatureArea : rainstormAreas) {
            Map<RainFeatureTime,Set<RainFeatureTime>> rainFeatureTimeSetMap = new HashMap<>();
            Map<String, Station> stationInfoMap = StationCache.getStationInfoMap();
            Set<RainFeatureTime> rainstormTimes1 = rainFeatureArea.getRainstormTimes();
            for (RainFeatureTime rainFeatureTime : rainstormTimes1) {
                Set<RainFeatureTime> rainFeatureTimes = new HashSet<>();
                rainFeatureTimes.add(rainFeatureTime);
                for (RainFeatureTime featureTime : rainstormTimes1) {
                    if (cheakInitDistance(rainFeatureTime, featureTime, stationInfoMap)){
                        rainFeatureTimes.add(featureTime);
                        rainFeatureTimeSetMap.put(rainFeatureTime,rainFeatureTimes);
                    }
                }
            }
            //找出最大的
            List<RainFeatureTime> rainFeatureTimeList = rainFeatureTimeSetMap.entrySet().stream()
                    .sorted((Map.Entry<RainFeatureTime, Set<RainFeatureTime>> o1, Map.Entry<RainFeatureTime, Set<RainFeatureTime>> o2) -> o2.getValue().size() - o1.getValue().size())
                    .map(entry -> entry.getKey()).collect(Collectors.toList())
                    .subList(0, 1);
            //最大的点周边的所有点
            Set<RainFeatureTime> rainFeatureTimes = rainFeatureTimeSetMap.get(rainFeatureTimeList.get(0));
            //接下来进行增补 如果这个和初始的大小一样就不用了就是这块 小于的话需要
            if (rainFeatureTimes.size() == rainstormTimes1.size()) {
                rainFeatureArea.setRainstormTimes(rainFeatureTimes);
            }else{
                //增补 先求差集 再循环 增补需要循环进行
                rainstormTimes1.removeAll(rainFeatureTimes);
                //循环增补
                for (int i = 0; i < rainstormTimes1.size(); i++) {
                    for (RainFeatureTime rainFeatureTime : rainstormTimes1) {
                        if(cheakSupplement(rainFeatureTimes, rainFeatureTime, stationInfoMap)){
                            rainFeatureTimes.add(rainFeatureTime);
                        }
                    }
                }
                rainFeatureArea.setRainstormTimes(rainFeatureTimes);
            }
        }
        //转换保存
        if (com.hxgis.common.utils.CollectionUtils.isNotBlank(rainstormAreas)){
            List<RainstormFeatureInfo> rainstormFeatureInfoList = new ArrayList<RainstormFeatureInfo>();
            for (RainFeatureArea rainFeatureArea : rainstormAreas) {
                if (rainFeatureArea.getRainstormTimes().size() > 3){
                    rainstormFeatureInfoList.addAll(rainFeatureArea.getRainstormInfoList());
                }
            }
            featureInfoRepository.saveBatch(rainstormFeatureInfoList);
        }
        log.info("{}到{},持续性区域暴雨特征数据保存完成",startTime,endTime);

        //todo yyy
    }

    @Override
    public List<SingleFrequencyVO> rainFeatureTarget(String startTime, String endTime) {
        List<SingleFrequencyVO> singleFrequencyVOS = new ArrayList<>();
        Map<String, Station> stationInfoMap = StationCache.getStationInfoMap();
        Map<String, Map<String, List<RainstormFeatureInfo>>> collect = getFeatureInfoGroupStNoAndCourseNum(startTime, endTime);
        if (CollectionUtils.isEmpty(collect)){
            return singleFrequencyVOS;
        }
        collect.forEach((stationNo,value) -> {
            if (!CollectionUtils.isEmpty(value)){
                SingleFrequencyVO singleFrequencyVO = new SingleFrequencyVO();
                singleFrequencyVO.setStationNo(stationNo);
                singleFrequencyVO.setLat(Double.parseDouble(stationInfoMap.get(stationNo).getLat()));
                singleFrequencyVO.setLon(Double.parseDouble(stationInfoMap.get(stationNo).getLon()));
                singleFrequencyVO.setCountNum(value.size());
                singleFrequencyVOS.add(singleFrequencyVO);
            }
        });
//        Collections.sort(singleFrequencyVOS,((o1, o2) -> {
//            return o1.getCountNum() - o2.getCountNum();
//        }));


        return singleFrequencyVOS;
    }

    @Override
    public List<SingleFrequencyVO> featureContinueDaysTarget(String startTime, String endTime, Integer continueDays, Integer flag) {
        Map<String, Station> stationInfoMap = StationCache.getStationInfoMap();
        Map<String, Map<String, List<RainstormFeatureInfo>>> collect = getFeatureInfoGroupStNoAndCourseNum(startTime, endTime);
        List<SingleFrequencyVO> singleFrequencyVOS = new ArrayList<>();
        if (CollectionUtils.isEmpty(collect)){
            return singleFrequencyVOS;
        }
        collect.forEach((stationNo,value) -> {
            Iterator<Map.Entry<String, List<RainstormFeatureInfo>>> iterator = value.entrySet().iterator();
            while(iterator.hasNext()){
                Map.Entry<String, List<RainstormFeatureInfo>> next = iterator.next();
                if (Objects.equals(flag,1)){
                    if (Objects.equals(continueDays, 3)){
                        if(next.getValue().size() != 3)
                            iterator.remove();//使用迭代器的remove()方法删除元素
                    }
                    if (Objects.equals(continueDays, 4)){
                        if(next.getValue().size() != 4)
                            iterator.remove();//使用迭代器的remove()方法删除元素
                    }
                    if (Objects.equals(continueDays, 5)){
                        if(next.getValue().size() < 5)
                            iterator.remove();//使用迭代器的remove()方法删除元素
                    }
                }
                if (Objects.equals(flag,2)){
                    double sum = next.getValue().stream().mapToDouble(RainstormFeatureInfo::getRainFall).sum();
                    double indexFlag = sum / 10 / 60;
                    if (Objects.equals(continueDays, 3)){
                        if(indexFlag < 3 || indexFlag > 5)
                            iterator.remove();//使用迭代器的remove()方法删除元素
                    }
                    if (Objects.equals(continueDays, 4)){
                        if(indexFlag < 6 || indexFlag > 8)
                            iterator.remove();//使用迭代器的remove()方法删除元素
                    }
                    if (Objects.equals(continueDays, 5)){
                        if(indexFlag < 9)
                            iterator.remove();//使用迭代器的remove()方法删除元素
                    }
                }

            }
        });

        collect.forEach((stationNo,value) -> {
            if (value.size() != 0){
                SingleFrequencyVO singleFrequencyVO = new SingleFrequencyVO();
                singleFrequencyVO.setLat(Double.parseDouble(stationInfoMap.get(stationNo).getLat()));
                singleFrequencyVO.setLon(Double.parseDouble(stationInfoMap.get(stationNo).getLon()));
                singleFrequencyVO.setStationNo(stationNo);
                singleFrequencyVO.setCountNum(value.size());
                singleFrequencyVOS.add(singleFrequencyVO);
            }
        });

                Collections.sort(singleFrequencyVOS,((o1, o2) -> {
            return o2.getCountNum() - o1.getCountNum();
        }));

        return singleFrequencyVOS;
    }

    @Override
    public List<AreaFrequencyVO> featureAreaFrequencyTarget(String startTime, String endTime, String flag) {
        List<Station> stations = stationService.selectAll();
        List<String> stationNos = new ArrayList<>();
        //筛选过滤  jdk1.8新特性
        if (Objects.equals(flag,"total")){
            stationNos = stations.stream().map(Station::getStationNo).map(String::valueOf).collect(Collectors.toList());
        }else if(Objects.equals(flag,"south")){
            Predicate<Station> southFilter = (f) -> (Double.parseDouble(f.getLat()) < 26d);
            stationNos = stations.stream().filter(southFilter).map(Station::getStationNo).map(String::valueOf).collect(Collectors.toList());
        }else if(Objects.equals(flag,"north")){
            Predicate<Station> northFilter = (f) -> (Double.parseDouble(f.getLat()) >= 34d);
            stationNos = stations.stream().filter(northFilter).map(Station::getStationNo).map(String::valueOf).collect(Collectors.toList());
        }else if(Objects.equals(flag,"middle")){
            Predicate<Station> middleFilter = (f) -> (Double.parseDouble(f.getLat()) > 26d && Double.parseDouble(f.getLat()) < 34d);
            stationNos = stations.stream().filter(middleFilter).map(Station::getStationNo).map(String::valueOf).collect(Collectors.toList());
        }
        //区分不同的区域的时候到时候将站点的相关信息加进来
        EsCondition condition = EsCondition.getEsCondition()
                .GTE("time", Long.valueOf(startTime))
                .LTE("time", Long.valueOf(endTime))
                .in("stationNo",com.hxgis.common.utils.CollectionUtils.convertCollectionString(stationNos))
                .eq("courseNum",null).not();
        condition.size(1000000);
        List<RainstormFeatureInfo> rainstormFeatureInfos = featureInfoRepository.selectList(condition);
        Map<String, Map<String, List<RainstormFeatureInfo>>> collect = rainstormFeatureInfos.stream()
                .collect(Collectors.groupingBy(RainstormFeatureInfo::getYear, Collectors.groupingBy(RainstormFeatureInfo::getCourseNum)));
        List<AreaFrequencyVO> areaFrequencyVOS = new ArrayList<>();
        if (CollectionUtils.isEmpty(collect)){
            return areaFrequencyVOS;
        }
        collect.forEach((year,value) -> {
            if (!CollectionUtils.isEmpty(value)){
                AreaFrequencyVO areaFrequencyVO = new AreaFrequencyVO();
                areaFrequencyVO.setYear(year);
                areaFrequencyVO.setCountNum(value.size());
                areaFrequencyVOS.add(areaFrequencyVO);
            }
        });
        Collections.sort(areaFrequencyVOS,((o1, o2) -> {
            return Integer.parseInt(o1.getYear()) - Integer.parseInt(o2.getYear());
        }));
        return areaFrequencyVOS;
    }


    private Map<String, Map<String, List<RainstormFeatureInfo>>> getFeatureInfoGroupStNoAndCourseNum(String startTime, String endTime) {
        EsCondition condition = EsCondition.getEsCondition()
                .GTE("time", Long.valueOf(startTime))
                .LTE("time", Long.valueOf(endTime))
                .eq("courseNum",null).not();
        condition.size(1000000);
        List<RainstormFeatureInfo> rainstormFeatureInfos = featureInfoRepository.selectList(condition);
        return rainstormFeatureInfos.stream()
                .collect(Collectors.groupingBy(RainstormFeatureInfo::getStationNo, Collectors.groupingBy(RainstormFeatureInfo::getCourseNum)));
    }

    private List<RainFeatureArea> rainstormAreas(List<RainFeatureTime> rainFeatureTimes){
        // 区域过程  key: 区域标识符号  value: 暴雨区域过程
        Map<String,RainFeatureArea> areaMap = new HashMap<String, RainFeatureArea>();
        for (RainFeatureTime rainFeatureTime : rainFeatureTimes) {
            if (!handlerRainstorm(rainFeatureTime,areaMap)){
                RainFeatureArea rainFeatureArea = new RainFeatureArea(rainFeatureTime);
                areaMap.put(rainFeatureArea.getAraFlag(),rainFeatureArea);
            }
        }
        List<RainFeatureArea> rainFeatureAreas = new ArrayList<RainFeatureArea>();
        areaMap.forEach((s, rainstormArea) -> {
            if (rainstormArea.getRainstormTimes().size()>=3){
                rainFeatureAreas.add(rainstormArea);
            }
        });
        return rainFeatureAreas;
    }

    /**
     * 暴雨区域过程处理
     * @param rainFeatureTime
     * @param areaMap
     * @return true 找到区域  false 没有找到区域
     */
    private boolean handlerRainstorm(RainFeatureTime rainFeatureTime,Map<String,RainFeatureArea> areaMap){
        List<String> mergeAreaFlag = new ArrayList<String>();
        for (String areaFlag:areaMap.keySet()){
            RainFeatureArea rainFeatureArea = areaMap.get(areaFlag);
            // 先进行条件判断
            if (rainFeatureArea.check(rainFeatureTime)){
                mergeAreaFlag.add(areaFlag);
            }
        }
        //找不到暴雨处理过程 返回false
        if (CollectionUtils.isEmpty(mergeAreaFlag)){
            return false;
        }
        RainFeatureArea rainFeatureArea = mergeAreaProcess(areaMap, mergeAreaFlag);
        rainFeatureArea.add(rainFeatureTime);
        //找到了暴雨过程
        return true;
    }

    /**
     * 合并区域过程
     */
    private RainFeatureArea mergeAreaProcess(Map<String,RainFeatureArea> areaMap,List<String> mergeAreaFlagList){
        RainFeatureArea rainFeatureArea = areaMap.get(mergeAreaFlagList.get(0));
        for (int i = 1; i < mergeAreaFlagList.size(); i++) {
            String areaFlag = mergeAreaFlagList.get(i);
            rainFeatureArea.merge(areaMap.get(areaFlag));
            areaMap.remove(areaFlag);
        }
        return rainFeatureArea;
    }


    public List<RainstormFeatureInfo> selectList(String startTime, String endTime, String ... stationNos){
        EsAggCondition esAggCondition = EsAggCondition.getInstance();
        esAggCondition.Group("time").size(100000);
        esAggCondition.getEsCondition()
                .GTE("time", Long.valueOf(startTime))
                .LTE("time", Long.valueOf(endTime))
                .in("stationNo", stationNos)
//                .gte("rainFall",500)
                .lte("rainFall",10000);
        List<String> times = featureInfoRepository.selectListAgg(esAggCondition, new DataWrapper<String>() {
            @Override
            public String wrapper(Map<String, Object> data) {
                return data.get("time").toString();
            }
        });
        EsCondition timeCondition = EsCondition.getEsCondition();
        timeCondition.in("time", com.hxgis.common.utils.CollectionUtils.convertCollectionString(times));
        timeCondition.size(1000000);
        return featureInfoRepository.selectList(timeCondition);
    }

    /**
     * 转换暴雨降雨时间比较
     * @param courseNumList
     * @return
     */
    private List<RainFeatureTime> converRainstormTime(Map<String, List<RainstormFeatureInfo>> courseNumList){
        List<RainFeatureTime> rainFeatureTimes = new ArrayList<RainFeatureTime>();
        courseNumList.forEach((s, rainstormFeatureInfos) -> {
            rainFeatureTimes.add(new RainFeatureTime(rainstormFeatureInfos));
        });
        rainFeatureTimes.sort((o1, o2) -> {
            return (int) (o1.getStartTime()-o2.getStartTime());
        });
        return rainFeatureTimes;
    }



    private Map<Long,RainstormFeatureInfo> transFeatureStrom(List<RainDayInfo> rainDayInfos, String stationNo) {
        log.info("当前计算的站点是：{}",stationNo);
        Map<Long, RainDayInfo> rainDayInfoMap = rainDayInfos.stream().collect(Collectors.toMap(RainDayInfo::getTime, value -> value,(v1, v2) -> v1));
//        List<String> times = rainDayInfos.stream().map(RainDayInfo::getTime).map(String::valueOf).collect(Collectors.toList());
//        //批量查feature
//        Map<Long, List<RainstormFeatureInfo>> collect1 = new HashMap<>();
//        List<RainstormFeatureInfo> rainstormFeatureInfos = queryFeatureByTime(times, stationNo);
//        if (!CollectionUtils.isEmpty(rainstormFeatureInfos)){
//            collect1 = rainstormFeatureInfos.stream().collect(Collectors.groupingBy(RainstormFeatureInfo::getTime));
//        }
//        //批量查日值降水
//        Map<Long, List<RainDayInfo>> collect2 = new HashMap<>();
//        List<RainDayInfo> rainDayInfos1 = queryRainFallByTime(times, stationNo);
//        if (!CollectionUtils.isEmpty(rainDayInfos1)){
//            collect2 = rainDayInfos1.stream().collect(Collectors.groupingBy(RainDayInfo::getTime));
//        }
        Map<Long,RainstormFeatureInfo> featureInfoMap = new HashMap<>();
        for (int i = 0; i < rainDayInfos.size(); i++) {
            RainDayInfo rainDayInfo = rainDayInfos.get(i);

            String preDay1 = TimeUtil.preDay(rainDayInfo.getTime().toString(), 1, TimeUtil.FORMATOR_YMD);
            String preDay2 = TimeUtil.preDay(rainDayInfo.getTime().toString(), 2, TimeUtil.FORMATOR_YMD);
            String preDay3 = TimeUtil.preDay(rainDayInfo.getTime().toString(), 3, TimeUtil.FORMATOR_YMD);
            String nextDay1 = TimeUtil.nextDay(rainDayInfo.getTime().toString(), 1, TimeUtil.FORMATOR_YMD);
            String nextDay2 = TimeUtil.nextDay(rainDayInfo.getTime().toString(), 2, TimeUtil.FORMATOR_YMD);

            //如果小于500 判断前三天是否满足每天大于500的要求
            if (rainDayInfo.getRainFall() < 500){
                RainstormFeatureInfo rainstormFeatureInfo = new RainstormFeatureInfo();
                if (i == 0){
                    //找前三天的数据，找的到再去找下一天的降雨数据两者之和大于500小于的不管
//                    RainstormFeatureInfo rainstormFeatureInfo_pre1 = CollectionUtils.isEmpty(collect1) ? null : CollectionUtils.isEmpty(collect1.get(Long.parseLong(preDay1))) ? null : collect1.get(Long.parseLong(preDay1)).get(0);
//                    RainstormFeatureInfo rainstormFeatureInfo_pre2 = CollectionUtils.isEmpty(collect1) ? null : CollectionUtils.isEmpty(collect1.get(Long.parseLong(preDay2))) ? null : collect1.get(Long.parseLong(preDay1)).get(0);
//                    RainstormFeatureInfo rainstormFeatureInfo_pre3 = CollectionUtils.isEmpty(collect1) ? null : CollectionUtils.isEmpty(collect1.get(Long.parseLong(preDay3))) ? null : collect1.get(Long.parseLong(preDay1)).get(0);

                    RainstormFeatureInfo rainstormFeatureInfo_pre1 = queryFeatureByTime(Long.valueOf(preDay1),stationNo);
                    RainstormFeatureInfo rainstormFeatureInfo_pre2 = queryFeatureByTime(Long.valueOf(preDay2),stationNo);
                    RainstormFeatureInfo rainstormFeatureInfo_pre3 = queryFeatureByTime(Long.valueOf(preDay3),stationNo);
                    if (Objects.nonNull(rainstormFeatureInfo_pre1) && Objects.nonNull(rainstormFeatureInfo_pre2) && Objects.nonNull(rainstormFeatureInfo_pre3)){
                        //前三天的已经是一个过程了再判断后一天的降雨
                        RainDayInfo rainDayInfo1 = rainDayInfoMap.get(Long.valueOf(nextDay1));
                        if (Objects.nonNull(rainDayInfo1) && rainDayInfo1.getRainFall() > 500){
                            //以前一天的为主
                            rainstormFeatureInfo.setId(rainDayInfo.getId());
                            rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                            rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                            rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                            rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                            rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                            rainstormFeatureInfo.setCourseNum(rainstormFeatureInfo_pre1.getCourseNum());
                            featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        }
                        continue;
                    }
                    continue;
                }else if (i == rainDayInfos.size() - 1){
                    //最后一天要去找后面一天的数据
                    RainstormFeatureInfo rainstormFeatureInfo_pre1 = featureInfoMap.get(Long.valueOf(preDay1));
                    RainstormFeatureInfo rainstormFeatureInfo_pre2 = featureInfoMap.get(Long.valueOf(preDay2));
                    RainstormFeatureInfo rainstormFeatureInfo_pre3 = featureInfoMap.get(Long.valueOf(preDay3));
                    if (Objects.nonNull(rainstormFeatureInfo_pre1) && Objects.nonNull(rainstormFeatureInfo_pre2) && Objects.nonNull(rainstormFeatureInfo_pre3)){
                        //前三天的已经是一个过程了再判断后一天的降雨 最后一天肯定为空 因为没数据 但是如果下次来了又满足大于500这个应该补上去 接下来走下面的可以补
                        RainDayInfo rainDayInfo_pre = queryRainFallByTime(Long.valueOf(nextDay1), stationNo);
                        if (Objects.nonNull(rainDayInfo_pre) && rainDayInfo_pre.getRainFall() > 500){
                            //以前一天的为主
                            rainstormFeatureInfo.setId(rainDayInfo.getId());
                            rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                            rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                            rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                            rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                            rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                            rainstormFeatureInfo.setCourseNum(rainstormFeatureInfo_pre1.getCourseNum());
                            featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        }
                        continue;
                    }
                    continue;

                }else{
                    //中间
                    RainstormFeatureInfo rainstormFeatureInfo_pre1 = featureInfoMap.get(Long.valueOf(preDay1));
                    RainstormFeatureInfo rainstormFeatureInfo_pre2 = featureInfoMap.get(Long.valueOf(preDay2));
                    RainstormFeatureInfo rainstormFeatureInfo_pre3 = featureInfoMap.get(Long.valueOf(preDay3));
//                    RainDayInfo rainDayInfo1 = rainDayInfoMap.get(Long.valueOf(nextDay1));
                    if (Objects.nonNull(rainstormFeatureInfo_pre1) && Objects.nonNull(rainstormFeatureInfo_pre2) && Objects.nonNull(rainstormFeatureInfo_pre3)){
                        //前三天的已经是一个过程了再判断后一天的降雨
                        RainDayInfo rainDayInfo_pre = rainDayInfoMap.get(Long.valueOf(nextDay1));
                        if (Objects.nonNull(rainDayInfo_pre) && rainDayInfo_pre.getRainFall() > 500){
                            //以前一天的为主
                            rainstormFeatureInfo.setId(rainDayInfo.getId());
                            rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                            rainstormFeatureInfo.setCourseNum(rainstormFeatureInfo_pre1.getCourseNum());
                            rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                            rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                            rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                            rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                            featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        }
                        continue;
                    }
                    continue;
                }
            }else if (rainDayInfo.getRainFall() > 500){
                RainstormFeatureInfo rainstormFeatureInfo = new RainstormFeatureInfo();
                if (i == 0){
//                    RainstormFeatureInfo rainstormFeatureInfo_pre = CollectionUtils.isEmpty(collect1) ? null : CollectionUtils.isEmpty(collect1.get(Long.parseLong(preDay1))) ? null : collect1.get(Long.parseLong(preDay1)).get(0);
                    RainstormFeatureInfo rainstormFeatureInfo_pre = queryFeatureByTime(Long.valueOf(preDay1),stationNo);
                    if (Objects.isNull(rainstormFeatureInfo_pre) || rainstormFeatureInfo_pre.getCourseNum() == null){
                        RainDayInfo rainDayInfo1 = rainDayInfoMap.get(Long.valueOf(nextDay1));
                        RainDayInfo rainDayInfo2 = rainDayInfoMap.get(Long.valueOf(nextDay2));
                        //第二第三天必须大于500
                        if(Objects.nonNull(rainDayInfo1) && rainDayInfo1.getRainFall() > 500 &&
                                Objects.nonNull(rainDayInfo2) && rainDayInfo2.getRainFall() > 500){
                            rainstormFeatureInfo.setId(rainDayInfo.getId());
                            rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                            rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                            rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                            rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                            rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                            rainstormFeatureInfo.setCourseNum(rainDayInfo.getStationNo() + rainDayInfo.getTime());
                            featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        }
                        continue;
                    }else{
                        //前一天找到了过程用前一天的数据
                        rainstormFeatureInfo.setId(rainDayInfo.getId());
                        rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                        rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                        rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                        rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                        rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                        rainstormFeatureInfo.setCourseNum(rainstormFeatureInfo_pre.getCourseNum());
                        featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        continue;
                    }
                }else if (i == rainDayInfos.size() - 1){
                    //最后一天要去找后面几天的数据 先找前一天的
                    RainstormFeatureInfo rainstormFeatureInfo_pre = featureInfoMap.get(Long.valueOf(preDay1));
                    if (Objects.isNull(rainstormFeatureInfo_pre) || rainstormFeatureInfo_pre.getCourseNum() == null){
                        //这是一个全新的过程
//                        RainDayInfo rainDayInfo1 = CollectionUtils.isEmpty(collect2) ? null : CollectionUtils.isEmpty(collect2.get(Long.parseLong(nextDay1))) ? null : collect2.get(Long.parseLong(nextDay1)).get(0);
//                        RainDayInfo rainDayInfo2 = CollectionUtils.isEmpty(collect2) ? null : CollectionUtils.isEmpty(collect2.get(Long.parseLong(nextDay2))) ? null : collect2.get(Long.parseLong(nextDay2)).get(0);

                        RainDayInfo rainDayInfo1 = queryRainFallByTime(Long.valueOf(nextDay1), stationNo);
                        RainDayInfo rainDayInfo2 = queryRainFallByTime(Long.valueOf(nextDay1), stationNo);
                        //第二第三天必须大于500
                        if(Objects.nonNull(rainDayInfo1) && rainDayInfo1.getRainFall() > 500 &&
                                Objects.nonNull(rainDayInfo2) && rainDayInfo2.getRainFall() > 500){
                            rainstormFeatureInfo.setId(rainDayInfo.getId());
                            rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                            rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                            rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                            rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                            rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                            rainstormFeatureInfo.setCourseNum(rainDayInfo.getStationNo() + rainDayInfo.getTime());
                            featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        }
                        continue;
                    }else{
                        rainstormFeatureInfo.setId(rainDayInfo.getId());
                        rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                        rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                        rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                        rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                        rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                        rainstormFeatureInfo.setCourseNum(rainstormFeatureInfo_pre.getCourseNum());
                        featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        continue;
                    }
                }else if (i == rainDayInfos.size() - 2){
                    //倒数第二天 找下一天从map中去寻找  下下天去es查询数据
                    RainstormFeatureInfo rainstormFeatureInfo_pre = featureInfoMap.get(Long.valueOf(preDay1));
                    if (Objects.isNull(rainstormFeatureInfo_pre) || rainstormFeatureInfo_pre.getCourseNum() == null){
                        //这是一个全新的过程
                        RainDayInfo rainDayInfo1 = rainDayInfoMap.get(Long.valueOf(nextDay1));
                        RainDayInfo rainDayInfo2 = queryRainFallByTime(Long.valueOf(nextDay2), stationNo);
                        //第二第三天必须大于500
                        if(Objects.nonNull(rainDayInfo1) && rainDayInfo1.getRainFall() > 500 &&
                                Objects.nonNull(rainDayInfo2) && rainDayInfo2.getRainFall() > 500){
                            rainstormFeatureInfo.setId(rainDayInfo.getId());
                            rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                            rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                            rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                            rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                            rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                            rainstormFeatureInfo.setCourseNum(rainDayInfo.getStationNo() + rainDayInfo.getTime());
                            featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        }
                        continue;
                    }else{
                        rainstormFeatureInfo.setId(rainDayInfo.getId());
                        rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                        rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                        rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                        rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                        rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                        rainstormFeatureInfo.setCourseNum(rainstormFeatureInfo_pre.getCourseNum());
                        featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        continue;
                    }
                }else{
                    //中间需要考虑多种情况
                    RainstormFeatureInfo rainstormFeatureInfo1 = featureInfoMap.get(Long.valueOf(preDay1));
                    if (Objects.isNull(rainstormFeatureInfo1) || rainstormFeatureInfo1.getCourseNum() == null){
                        RainDayInfo rainDayInfo1 = rainDayInfoMap.get(Long.valueOf(nextDay1));
                        RainDayInfo rainDayInfo2 = rainDayInfoMap.get(Long.valueOf(nextDay2));
                        //第二第三天必须大于500
                        if(Objects.nonNull(rainDayInfo1) && rainDayInfo1.getRainFall() > 500 &&
                                Objects.nonNull(rainDayInfo2) && rainDayInfo2.getRainFall() > 500){
                            rainstormFeatureInfo.setId(rainDayInfo.getId());
                            rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                            rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                            rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                            rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                            rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                            rainstormFeatureInfo.setCourseNum(rainDayInfo.getStationNo() + rainDayInfo.getTime());
                            featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                            continue;
                        }
                    }else{
                        rainstormFeatureInfo.setId(rainDayInfo.getId());
                        rainstormFeatureInfo.setDays(rainDayInfo.getDays());
                        rainstormFeatureInfo.setTime(rainDayInfo.getTime().intValue());
                        rainstormFeatureInfo.setStationNo(rainDayInfo.getStationNo());
                        rainstormFeatureInfo.setYear(rainDayInfo.getYear());
                        rainstormFeatureInfo.setRainFall(rainDayInfo.getRainFall());
                        rainstormFeatureInfo.setCourseNum(rainstormFeatureInfo1.getCourseNum());
                        featureInfoMap.put(rainDayInfo.getTime(),rainstormFeatureInfo);
                        continue;
                    }
                }
            }
        }
        return featureInfoMap;
    }

    /**
     * 查询某一天的中国持续性暴雨特征降雨量数据
     * @param times
     * @param stationNo
     * @return
     */
    private RainstormFeatureInfo queryFeatureByTime(Long times, String stationNo) {
        EsCondition featuresCondition = EsCondition.getEsCondition();
//        featuresCondition.in("time", com.hxgis.common.utils.CollectionUtils.convertCollectionString(times));
        featuresCondition.eq("time", times);
        featuresCondition.eq("stationNo",stationNo);
        featuresCondition.size(100000);
        List<RainstormFeatureInfo> rainstormFeatureInfos = featureInfoRepository.selectList(featuresCondition);
        return CollectionUtils.isEmpty(rainstormFeatureInfos) ? null : rainstormFeatureInfos.get(0);
    }


    /**
     * 查询某一天的降雨量数据
     * @param time
     * @param stationNo
     * @return
     */
    @Override
    public RainDayInfo queryRainFallByTime(Long time, String stationNo) {
        EsCondition rainCondition = EsCondition.getEsCondition();
//        rainCondition.in("time",com.hxgis.common.utils.CollectionUtils.convertCollectionString(times));
        rainCondition.eq("time",time).lte("rainFall",20000);
        rainCondition.eq("stationNo",stationNo);
        rainCondition.size(100000);
        List<RainDayInfo> rainDayInfos = rainDayInfoRepository.selectList(rainCondition);
        return CollectionUtils.isEmpty(rainDayInfos) ? null : rainDayInfos.get(0);
    }



    private boolean cheakInitDistance(RainFeatureTime rainFeatureTime1, RainFeatureTime rainFeatureTime2, Map<String, Station> stationInfoMap){
        Station station1 = stationInfoMap.get(rainFeatureTime1.getStationNo());
        Station station2 = stationInfoMap.get(rainFeatureTime2.getStationNo());
        double sqrt = Math.sqrt(Math.pow((Double.parseDouble(station1.getLon()) - Double.parseDouble(station2.getLon())), 2) +
                Math.pow((Double.parseDouble(station1.getLat()) - Double.parseDouble(station2.getLat())), 2));
        if (sqrt < 5){
            return true;
        }
        return false;
    }

    private boolean cheakSupplement(Set<RainFeatureTime> rainFeatureTimes, RainFeatureTime rainFeatureTime, Map<String, Station> stationInfoMap){
        for (RainFeatureTime featureTime : rainFeatureTimes) {
            Station station1 = stationInfoMap.get(featureTime.getStationNo());
            Station station2 = stationInfoMap.get(rainFeatureTime.getStationNo());
            double sqrt = Math.sqrt(Math.pow((Double.parseDouble(station1.getLon()) - Double.parseDouble(station2.getLon())), 2) +
                    Math.pow((Double.parseDouble(station1.getLat()) - Double.parseDouble(station2.getLat())), 2));
            if (sqrt < 2){
                return true;
            }
        }
        return false;
    }




}
